/**
 * Copyright &copy; 2015-2020 <a href="http://www.workless.cn/">JeePlus</a> All rights reserved.
 */
package com.workless.modules.sys.web;

import cn.hutool.crypto.SecureUtil;
import com.auth0.jwt.JWT;
import com.google.common.collect.Maps;
import com.workless.common.json.AjaxJson;
import com.workless.common.utils.CacheUtils;
import com.workless.config.properties.JeePlusProperites;
import com.workless.core.web.BaseController;
import com.workless.core.web.GlobalErrorController;
import com.workless.modules.sys.entity.User;
import com.workless.modules.sys.mapper.UserMapper;
import com.workless.modules.sys.security.util.JWTUtil;
import com.workless.modules.sys.service.UserService;
import com.workless.modules.sys.utils.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import sun.security.provider.MD5;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Base64;
import java.util.Map;

/**
 * 登录Controller
 *
 * @author workless
 * @version 2016-5-31
 */
@RestController
@Api(tags = "登录管理")
public class LoginController extends BaseController {


    @Autowired
    JeePlusProperites jeePlusProperites;
    @Autowired
    private UserMapper userMapper;



    @PostMapping("/sys/login")
    @ApiOperation("登录接口")
    public AjaxJson login(@RequestParam("token") String token) throws UnsupportedEncodingException {
//        System.out.println(token);
        final Base64.Decoder decoder = Base64.getDecoder();//解密
        final Base64.Encoder encoder = Base64.getEncoder();//加密
        AjaxJson j = new AjaxJson();
//         s = null;
        if (StringUtils.isNotBlank(token)){
            String  s = new String(decoder.decode(token), "UTF-8");

            String[] ss = StringUtils.split(s,'&');
            String sid = ss[0];
            String userId = ss[1];
            String sign = ss[2];
            System.out.println("sid="+sid);
            System.out.println("userId="+userId);
            System.out.println("sign="+sign);

            String data_key="xlc3NWbXBKTldWWFJYbGxSM2";
            String text ="sid="+sid+"&userId="+userId+"&data_key="+data_key;
//            System.out.println(text+"==text");

            final byte[] textByte = text.getBytes("UTF-8");
//            System.out.println(Arrays.toString(textByte)+"==textByte");
            String localSign = SecureUtil.md5(encoder.encodeToString(textByte));
//            System.out.println(encoder.encodeToString(textByte)+"==encoder.encodeToString(textByte)");
//            System.out.println(localSign+"==localSign");

            if(localSign.equals(sign)) {//"workless_"+sid+"_"+userId

                if (UserUtils.get(userId)==null) {
                    userMapper.execInsertSql(" insert into sys_user(id, company_id, login_name, password ) values('" + userId + "', '" + sid + "', 'workless_" + userId + "', '0f74d5bc7882309a60a0d230719c89d9fed1245e6ccda42470026adc' ) ");
                }else {
                    userMapper.execUpdateSql("update sys_user set company_id = "+sid+" where id = "+userId+"");
                }
                String username = "workless_" + userId;
                String password = "admin";
                User user = UserUtils.getByLoginName(username);
                if (user != null && UserService.validatePassword(password, user.getPassword())) {

                    if (JeePlusProperites.NO.equals(user.getLoginFlag())) {
                        j.setSuccess(false);
                        j.setMsg("禁止访问!");
                    } else {
                        j.setSuccess(true);
                        j.put(JWTUtil.TOKEN, JWTUtil.createAccessToken(username, user.getPassword()));
                        j.put(JWTUtil.REFRESH_TOKEN, JWTUtil.createRefreshToken(username, user.getPassword()));
                    }
                }
            }
        }
        else {
            j.setSuccess(false);
            j.setMsg("访问失败!");
        }
        return j;
    }
//            if ()
//            userMapper.execInsertSql(" insert into sys_user(id, company_id, login_name, password ) values('"+userId+"', '"+sid+"', 'workless_"+userId+"', '0f74d5bc7882309a60a0d230719c89d9fed1245e6ccda42470026adc' ) ");
//            j.put(JWTUtil.TOKEN, JWTUtil.createAccessToken("workless_"+userId, "0f74d5bc7882309a60a0d230719c89d9fed1245e6ccda42470026adc"));
//            j.put(JWTUtil.REFRESH_TOKEN, JWTUtil.createRefreshToken("workless_"+userId, "0f74d5bc7882309a60a0d230719c89d9fed1245e6ccda42470026adc"));
////            j.put(JWTUtil.INFO, JWTUtil.createAccessInfo(sid, userId));
////            j.put(JWTUtil.REFRESH_INFO, JWTUtil.createRefreshInfo(sid, userId));
//        }else {
//            j.setSuccess(false);
//            j.setMsg("访问失败!");
//        }


//        User user = UserUtils.getByLoginName(userName);
//        if (user != null && UserService.validatePassword(password, user.getPassword())) {

//            if (JeePlusProperites.NO.equals(user.getLoginFlag())){
//                j.setSuccess(false);
//                j.setMsg("该用户已经被禁止登陆!");
//            }else {
//                j.setSuccess(true);
//                j.put(JWTUtil.TOKEN, JWTUtil.createAccessToken(userName, user.getPassword()));
//                j.put(JWTUtil.REFRESH_TOKEN, JWTUtil.createRefreshToken(userName, user.getPassword()));

//            }

//        }
//        else {

//        }

    @GetMapping("/sys/refreshToken")
    @ApiOperation("刷新token")
    public AjaxJson accessTokenRefresh(String refreshToken, HttpServletRequest request, HttpServletResponse response){

        if (JWTUtil.verify(refreshToken) == 1) {
            GlobalErrorController.response4022(request, response);

        }else if (JWTUtil.verify(refreshToken) == 2) {
            return AjaxJson.error("密码错误");
        }

        String loginName = JWTUtil.getLoginName(refreshToken);
        String password = UserUtils.getByLoginName(loginName).getPassword();
        //创建新的accessToken
        String accessToken = JWTUtil.createAccessToken(loginName, password);

        //下面判断是否刷新 REFRESH_TOKEN，如果refreshToken 快过期了 需要重新生成一个替换掉
        long minTimeOfRefreshToken = 2*JeePlusProperites.newInstance().getEXPIRE_TIME();//REFRESH_TOKEN 有效时长是应该为accessToken有效时长的2倍
        Long refreshTokenExpirationTime = JWT.decode(refreshToken).getExpiresAt().getTime();//refreshToken创建的起始时间点
        //(refreshToken过期时间- 当前时间点) 表示refreshToken还剩余的有效时长，如果小于2倍accessToken时长 ，则刷新 REFRESH_TOKEN
        if(refreshTokenExpirationTime - System.currentTimeMillis() <= minTimeOfRefreshToken){
            //刷新refreshToken
            refreshToken = JWTUtil.createRefreshToken(loginName, password);
        }

        return AjaxJson.success().put(JWTUtil.TOKEN, accessToken).put(JWTUtil.REFRESH_TOKEN, refreshToken);
    }



    /**
     * 退出登录
     * @throws IOException
     */
    @ApiOperation("用户退出")
    @GetMapping("/sys/logout")
    public AjaxJson logout() {
        AjaxJson j = new AjaxJson();
        String token = UserUtils.getToken();
        if (StringUtils.isNotBlank(token)) {
            UserUtils.clearCache();
            UserUtils.getSubject().logout();
        }
        j.setMsg("退出成功");
        return j;
    }


    /**
     * 是否是验证码登录
     *
     * @param useruame 用户名
     * @param isFail   计数加1
     * @param clean    计数清零
     * @return
     */
    @SuppressWarnings("unchecked")
    public static boolean isValidateCodeLogin(String useruame, boolean isFail, boolean clean) {
        Map<String, Integer> loginFailMap = (Map<String, Integer>) CacheUtils.get("loginFailMap");
        if (loginFailMap == null) {
            loginFailMap = Maps.newHashMap();
            CacheUtils.put("loginFailMap", loginFailMap);
        }
        Integer loginFailNum = loginFailMap.get(useruame);
        if (loginFailNum == null) {
            loginFailNum = 0;
        }
        if (isFail) {
            loginFailNum++;
            loginFailMap.put(useruame, loginFailNum);
        }
        if (clean) {
            loginFailMap.remove(useruame);
        }
        return loginFailNum >= 3;
    }


}
